package com.voja.salonschedule;

import java.util.ArrayList;

import com.voja.AndroidUtils.Application;
import com.voja.AndroidUtils.Application.Click;
import com.voja.AndroidUtils.Application.Command;
import com.voja.AndroidUtils.Application.CommandWrapper;
import com.voja.salonschedule.customers.Adapter;
import com.voja.salonschedule.customers.CreditAdapter;
import com.voja.salonschedule.customers.PhotoAdapter;
import com.voja.salonschedule.customers.PhotoOptionClickListener;
import com.voja.salonschedule.customers.TmpFile;
import com.voja.salonschedule.data.Customer;
import com.voja.salonschedule.data.CustomerBalance;
import com.voja.salonschedule.data.Customer.CustomerItem;
import com.voja.salonschedule.data.CustomerBalance.Balance;
import com.voja.salonschedule.data.CustomerBalance.BalanceItem;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.SearchManager;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.ContactsContract;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RelativeLayout;
import android.support.v7.widget.SearchView;
import android.widget.TextView;

public class Customers extends BaseChildActivity {
    
	public static final int  ACTION_IMPORT_CONTACT = 100;
	public static final int  ACTION_CREDIT_DETAILS = 101;
	
    public static final String KEY_CUSTOMER_NAME = "customer-name";
    public static final String KEY_EDITING       = "editing";
    public static final String KEY_CONTACT_URI   = "contact-uri";
    public static final String TYPE_PICTURES = Environment.DIRECTORY_PICTURES;
    
    private Resources res;
    public static Adapter adapter;
    
    private Customer modelCustomer;
    private ArrayList<CustomerItem> customers;
    
    private Context context = this;
    
    public static Command cmdAddCredit;
    public static CustomerItem customer;
    
    public static Intent originalIntent;
    public static CreditAdapter creditAdapter;
    public static CustomerBalance modelCustomerBalance;
    
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		res = getResources();
	}
	
	@Override
	public void onResume() {
	    super.onResume();
	    
	    Application.setContext(this);
	    Application.DEFAULT_MESSAGE_TITLE = res.getString(R.string.Customers);
	    
	    modelCustomer = new Customer(this);
	    
	    handleIntent(getIntent());
	}
	
	@Override
	public void onDestroy() {
	    // if for some reason tmp-file still exists, delete it 
	    TmpFile.getInstance(this, TYPE_PICTURES).delete();
	    
	    super.onDestroy();
	}
	
	@SuppressLint("NewApi")
    @Override
	public boolean onCreateOptionsMenu(Menu menu) {
		String action = getIntent().getAction();
		action = action == null ? "" : action;
	    
		if (action.equals(Intent.ACTION_EDIT)) {
	        getMenuInflater().inflate(R.menu.customer_edit, menu);
	    } else if (action.equals(Intent.ACTION_INSERT)) {
	    	getMenuInflater().inflate(R.menu.customer_import, menu);
	    } else if (action.equals(ACTION_CREDIT_DETAILS+"")) {
	    	getMenuInflater().inflate(R.menu.customer_credit_details, menu);
	    } else {
	        getMenuInflater().inflate(R.menu.customers, menu);
	        
	        // SEARCH
            SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
            MenuItem menuItem = menu.findItem(R.id.menuSearch);
            
            // check if search from ActionBar is possible
            SearchView searchView;
            try {
	            searchView = (SearchView)menuItem.getActionView();
	            menuItem.setVisible(true);
            } catch (NoSuchMethodError e) {
            	menuItem.setVisible(false);
            	return super.onCreateOptionsMenu(menu);
            }
            
            
            searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
            searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
               
                @Override
                public boolean onQueryTextSubmit(String keyword) {
                    list(keyword);
                    return true;
                }
               
                @Override
                public boolean onQueryTextChange(String keyword) {
                    list(keyword);
                    return true;
                }
            });

	    }
	    
	    return super.onCreateOptionsMenu(menu);
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    switch(item.getItemId()) {
	    case R.id.menuAdd:
	        addCustomer();
	        break;
	    case R.id.menuDelete:
	        deleteCustomer(true);
	        break;
	    case R.id.menuSave:
	        saveCustomer();
	        break;
	    case R.id.menuImport:
	    	pickContact();
	    	break;
	    case R.id.menuImportDo:
	    	importContactDo();
	    	break;
	    	
	    case R.id.menuCreditDetails:
	    	creditDetailsLaunch(customer.name);
	    	break;
	    	
	    case R.id.menuCreditAdd:
	    	addCredit();
	    	break;
	    }
	    
	    return super.onOptionsItemSelected(item);
	}
	
	@Override
	public void onActivityResult(int request, int result, Intent intent) {
	    boolean success = result == RESULT_OK;
	    
	    TmpFile tmpFile = TmpFile.getInstance(this, TYPE_PICTURES);
	    Bitmap bm = null;
	    ImageView image = ((ImageView)findViewById(R.id.imgCustomer));
	    
	    if (success) {
	        bm = PhotoOptionClickListener.handleRequest(this, request, intent);
	    }

	    switch(request){
	    case PhotoOptionClickListener.IMAGE_VIEWED:
            tmpFile.delete();
            break;
            
        case PhotoOptionClickListener.IMAGE_CROPPED:
            if (bm != null) {
                image.setImageBitmap(bm);
            }
            
            tmpFile.delete();
            break;
            
        case ACTION_IMPORT_CONTACT:
        	if (success) {
	        	Uri uri = intent.getData();
	        	if (uri != null) {
		        	Intent i = new Intent(this, Customers.class);
		        	i.setAction(Intent.ACTION_INSERT);
		        	i.putExtra(KEY_CONTACT_URI, uri.toString());
		        	startActivity(i);
	        	}
        	}
        	break;
        }
	    
	    super.onActivityResult(request, result, intent);
	}
	
	private void handleIntent(Intent intent) {
	    String action = intent.getAction();
	    action = action == null ? "" : action;
	    
	    originalIntent = intent;
	    
	    // EDIT CUSTOMER
	    if(action.equals(Intent.ACTION_EDIT)) {
	        String customerName = getExtra(KEY_CUSTOMER_NAME);
	        edit(customerName);
	        
	    // DELETE CUSTOMER
	    } else if(action.equals(Intent.ACTION_DELETE)) {
	        String extra = getExtra(KEY_EDITING);
            boolean editing = false;
            if (extra != null) {
                editing = Boolean.valueOf(extra);
            }
            deleteCustomer(editing);
        
        // IMPORT CONTACT
	    } else if(action.equals(Intent.ACTION_INSERT)) {
	    	String uri = getExtra(KEY_CONTACT_URI);
	    	importContact(Uri.parse(uri));
	    
	    // CREDIT DETAILS
	    } else if (action.equals(ACTION_CREDIT_DETAILS+"")) {
	    	String customerName = getExtra(KEY_CUSTOMER_NAME);
	    	creditDetails(customerName);
	    	
	    // CUSTOMERS LIST
	    } else {
	        String keyword = getExtra("keyword");
	        list(keyword);
	    }
	    
	    Index.initAd(this);
	}
	
	private void list(String keyword) {
	    setContentView(R.layout.customers);
	    
	    // load customers
	    customers = modelCustomer.getCustomers(keyword);
	    
	    // get list-view
	    ListView list = (ListView)findViewById(R.id.listCustomers);
	    
	    // set click-listener
	    list.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> list, View view, int position, long id) {
                CustomerItem customer = (CustomerItem)list.getAdapter().getItem(position);
                Intent intent = new Intent(context, Customers.class);
                intent.setAction(Intent.ACTION_EDIT);
                intent.putExtra(KEY_CUSTOMER_NAME, customer.name);
                startActivity(intent);
            }
        });
	    
	    // set list-adapter
	    adapter = new Adapter(this, R.layout.customer_item, customers, keyword);
	    list.setAdapter(adapter);
	    
	    View emptyView = findViewById(R.id.noCustomers);
	    emptyView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addCustomer();
            }
        });
	    list.setEmptyView(emptyView);
	    
	}
	
	private void edit(String customerName) {
	    setContentView(R.layout.customer_edit);
	    
	    if (customerName != null) {
	        customer = modelCustomer.getCustomer(customerName);
	        if (customer != null) {
	            // get elements
	            TextView name0 = (TextView)findViewById(R.id.txtCustomerName);
	            EditText name  = (EditText)findViewById(R.id.editCustomerName);
	            EditText phone = (EditText)findViewById(R.id.editCustomerPhone);
	            ImageView img  = (ImageView)findViewById(R.id.imgCustomer);
	            
	            // load input-data
	            name0.setText(customer.name);
	            name.setText(customer.name);
	            phone.setText(customer.phone);
	            img.setImageBitmap(customer.bitmap(R.drawable.contact));
	            
	            // set events
	            img.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        showImageDialog(customer);
                    }
                });
	            
	            // balance
	            updateBalanceField(customer);
	            
	            initAddCreditCommand(customer);
	        }
	    }
	}
	
	public void updateBalanceField(String customerName) {
		CustomerItem customer = modelCustomer.getCustomer(customerName);
		updateBalanceField(customer);
	}
	public void updateBalanceField(CustomerItem customer) {
        TextView txtBalance = (TextView)findViewById(R.id.txtCreditBalance);
        if (txtBalance != null) {
        	Balance balance = customer.getBalance();
        	updateBalanceTxt(txtBalance, balance);
        }
	}
	
	public void showImageDialog(CustomerItem customer) {
	    AlertDialog.Builder builder = new AlertDialog.Builder(this);
	    String[] options = res.getStringArray(R.array.customerImageOptions);
	    PhotoAdapter adapter = new PhotoAdapter(this, R.layout.customer_photo_option, customer, options);
	    builder
	        .setTitle(R.string.customerImage)
	        .setAdapter(adapter, adapter.listener)
	        .create()
	        .show();
	}
	
	private void addCustomer() {
	    Command command = new Command(){
            public void execute() {
                EditText edit = (EditText)Application.dialogView;
                CustomerItem customer = new CustomerItem();
                customer.name = edit.getText().toString().trim();
                if (! customer.name.equals("")) {
                    if (customers.indexOf(customer)<0) {
                        if (modelCustomer.save(customer)) {
                            customers.add(customer);
                            adapter.notifyDataSetChanged();
                        }
                    } else {
                        Application.alert(res.getString(R.string.msgCustomerAlreadyExist));
                    }
                }
            }
        };
       
        Click ok = new Click("OK", new CommandWrapper(command));
        String customerName = res.getString(R.string.CustomerName);
       
        Application.setContext(this);
        Application.prompt("", "", ok, customerName);

	}
	
	private void deleteCustomer(boolean editing) {
	    deleteCustomer(getExtra(KEY_CUSTOMER_NAME), editing);
	}
	
	public void deleteCustomer(final String customerName, final boolean editing) {
	    CommandWrapper del = new CommandWrapper(new Command() {
	        public void execute() {
	            modelCustomer.delete(customerName);
	            if (editing) {
	                finish();
	            } else {
	                list(adapter.keyword);
	            }
	        }
	    });
	    
	    Click yes = new Click(res.getString(R.string.Yes), del);
	    Click no  = new Click(res.getString(R.string.No), new CommandWrapper(Command.NOOP));
	    Application.confirm(res.getString(R.string.msgConfirmDelete), yes, no);
	}
	
	public void saveCustomer() {
	    TextView tvName  = (TextView)findViewById(R.id.txtCustomerName);
        EditText etName  = (EditText)findViewById(R.id.editCustomerName);
        EditText etPhone = (EditText)findViewById(R.id.editCustomerPhone);
        
        String name    = tvName.getText().toString();
        CustomerItem c = modelCustomer.getCustomer(name);
        c.name  = etName.getText().toString();
        c.phone = etPhone.getText().toString();
        
        if (modelCustomer.update(c, name)) {
            finish();
        } else {
            Application.alert("Save failed.");
        }
	}
	
	public void pickContact() {
		Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
		startActivityForResult(intent, ACTION_IMPORT_CONTACT);
	}
	
	@SuppressLint("InlinedApi")
	public void importContact(Uri uri) {
		setContentView(R.layout.customer_import);
		setTitle(R.string.importFromContacts);
		
		Cursor c = managedQuery(uri, null, null, null, null);
		if (c.moveToFirst()) {
			String indxId    = ContactsContract.Contacts._ID;
			String id    	= c.getString(c.getColumnIndex(indxId));
			
			String indxName  = ContactsContract.Contacts.DISPLAY_NAME;
			String name		= c.getString(c.getColumnIndex(indxName));
			
			String indxPhone = ContactsContract.Contacts.HAS_PHONE_NUMBER;
			String hasPhone = c.getString(c.getColumnIndex(indxPhone));
			
			String photo = "";
			try {
				photo	= c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts.PHOTO_URI));
			} catch(IllegalArgumentException e) {
				Uri cUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(id));
				photo = Uri.withAppendedPath(cUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY).toString();
			}
			
			// name
			EditText etName = (EditText)findViewById(R.id.etName);
			etName.setText(name);
			
			// photo
			RelativeLayout rlPhoto = (RelativeLayout)findViewById(R.id.lytPhoto);
			try {
				Uri uriPhoto = Uri.parse(photo);
				ImageView imgPhoto = (ImageView)findViewById(R.id.imgPhoto);
				imgPhoto.setImageURI(uriPhoto);
			} catch(NullPointerException e) {
				rlPhoto.setVisibility(View.GONE);
				CheckBox cbPhoto = (CheckBox)findViewById(R.id.chkPhoto);
				cbPhoto.setChecked(false);
			}
			
			// phones
			RadioGroup groupPhones = (RadioGroup)findViewById(R.id.groupPhones);
			if (hasPhone.equalsIgnoreCase("1")) {
				Cursor cPhones = getContentResolver().query(
					ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, 
					ContactsContract.CommonDataKinds.Phone.CONTACT_ID +"="+id, null, null);
				
				while (cPhones.moveToNext()) {
					String num = cPhones.getString(cPhones.getColumnIndex("data1"));
					num = num.replaceAll("[^\\d]", "");
					
					RadioButton rb = new RadioButton(this);
					rb.setText(num);
					rb.setId(cPhones.getPosition());
					if (cPhones.getPosition() == 0) {
						rb.setChecked(true);
					}
					
					groupPhones.addView(rb);
				}
			}
			
		} else {
			Application.alert(res.getString(R.string.Error) + ": " + uri);
		}
	}
	
	public void importContactDo() {
		CustomerItem customer = new CustomerItem();
		
		// name
		EditText etName = (EditText)findViewById(R.id.etName);
		customer.name = etName.getText().toString();
		
		// image
		CheckBox chkImage = (CheckBox)findViewById(R.id.chkPhoto);
		if (chkImage.isChecked()) {
			ImageView img = (ImageView)findViewById(R.id.imgPhoto);
			customer.loadImageFromView(img);
		}
		
		// phones
		RadioGroup groupPhones = (RadioGroup)findViewById(R.id.groupPhones);
		for (int i=0; i<groupPhones.getChildCount(); i++) {
			RadioButton rb = (RadioButton)groupPhones.getChildAt(i);
			if (rb.isChecked()) {
				customer.phone = rb.getText().toString();
				break;
			}
		}
		
		if (modelCustomer.save(customer)) {
			finish();
		} else {
			Application.alert("Error save.");
		}
	}
	
	public void addCredit() {
		Click clickSubmit = new Click(res.getString(R.string.Add), new CommandWrapper(cmdAddCredit));
		Click clickCancel = new Click(res.getString(R.string.Cancel), new CommandWrapper(Command.NOOP));
		String addMoneyQuestion = res.getString(R.string.moneyAddQuestion);
		String addMoney   		= res.getString(R.string.moneyAdd);
		Application.prompt(addMoneyQuestion, "", clickSubmit, clickCancel, addMoney);
	}
	
	public void initAddCreditCommand(final CustomerItem customer) {
		final CustomerBalance model = new CustomerBalance(context);
		cmdAddCredit = new Command() {
			
			@Override
			public void execute() {
				EditText edit = (EditText)Application.dialogView;
				String amountString = edit.getText()
										  .toString()
										  .replaceAll("[^\\d\\.]", "")
										  .replaceAll("^[^\\d]", "")
										  .replaceAll("[^\\d]$", "");
				if(amountString.length()>0) {
					double amount = Double.parseDouble(amountString);
					if (model.addCredit(customer.name, amount)) {
						Application.toast(res.getString(R.string.moneyAddSuccess))
								   .show();
						
						String customerName = getExtra(KEY_CUSTOMER_NAME, originalIntent);
						if (originalIntent.getAction() == ""+ACTION_CREDIT_DETAILS) {
							ArrayList<BalanceItem> data = modelCustomerBalance.details(customerName);
							creditAdapter.setItems(data);
						} else {
							updateBalanceField(customer);
						}
					} else {
						Application.alert(res.getString(R.string.moneyAddError));
					}
				}
			}
		};
	}
	
	public void creditDetailsLaunch(String name) {
		Intent i = new Intent(context, Customers.class);
		i.setAction(ACTION_CREDIT_DETAILS+"");
		i.putExtra(KEY_CUSTOMER_NAME, name);
		startActivity(i);
	}
	
	public void creditDetailsLaunch(View v) {
		creditDetailsLaunch(customer.name);
	}
	
	public void creditDetails(String customerName) {
		setContentView(R.layout.customer_credit_details);
		
		setTitle(customerName);
		
		modelCustomerBalance = new CustomerBalance(context);
		ArrayList<BalanceItem> details = modelCustomerBalance.details(customerName);
		creditAdapter = new CreditAdapter(this, R.layout.customer_credit_detail, details);
		ListView list = (ListView)findViewById(R.id.listCredit);
		list.setAdapter(creditAdapter);
	} 
	
	private void updateBalanceTxt(TextView tv, Balance balance) {
		tv.setText(balance.formatted());
		tv.setTextColor(balance.getColor());
	}
}
